(function (fruit, util, dom, Element, global) {
    var engine=fruit.eventEngine;
    fruit.ui.define("fruit.ui.popupContainer",{
        singleton: true,
        view:{
            props:{
                'class':'fruit f-popupContainer'
            }
        }
    });


    fruit.ready(function(){
        var popupContainer = new fruit.ui.popupContainer();
        fruit.app.append(popupContainer);
        fruit.app.popupContainer = popupContainer;
    });


    /**
     * @class fruit.app
     */
    fruit.define("fruit.app", {
        singleton: true,
        properties: {
        },
        methods: {
            config:{},
            /**
             * append component to body or container
             * @param component
             * @param containerSelector id or dom element
             */
            append: function (component, containerSelector) {
                var targetDOM;
                if (containerSelector) {
                    targetDOM = util.isDom(containerSelector) ? containerSelector : global.document.querySelector(containerSelector);
                }
                var target = Element.resolve(targetDOM || document.body);
                dom.appendChild(target._element, component._element);
            },
            on: function (eventType, fn, context) {
                if (eventType) {
                    engine.addEventListener(window,eventType, function (event) {
                        fn.call(context || this, event);
                    }, false);
                }
            }
        }
    });

    /**
     * @class fruit.router
     */
    fruit.define("fruit.router", {
        singleton: true,
        events: ['HashChange'],
        methods: {
            routerMap: {},
            routerRegMap: [],
            init: function () {
                fruit.app.on("hashchange", function () {
                    this._parseURL();
                }, this);
                this.active = false;
            },
            _parseURL: function () {
                if (this.active) {
                    var url = window.location.href.split("#");
                    var hash = url[1];
                    if (hash) {
                        var params = hash.split("/");
                        var router = params ? params.shift() : hash;
                    }
                    this.baseURL = url[0];
                    this.exec(router, params || []);
                }
            },
            /**
             * redirect page to certain url
             * @param url
             * @param silent
             * @returns {boolean}
             * @example fruit.router.redirect("task/detail/1");
             */
            redirect: function (url, silent) {
                if (!this.active) {
                    return false;
                }
                if (silent) {
                    this.active = false;
                    window.location.href = this.baseURL + "#" + url;
                    this.active = true;
                } else {
                    window.location.href = this.baseURL + "#" + url;
                }

            },
            /**
             * register route map
             * @param {Object} map
             * @param inContext function context
             */
            registerRouteMap: function (map, inContext) {
                var context = inContext || this;
                util.each(map, function (rule, key) {
                    if (this._isRegExp(key)) {
                        //Reg router map
                        var reg = key.substr(1, key.length - 2);
                        this.routerRegMap.push({
                            reg: reg,
                            action: rule,
                            context: context
                        });
                    } else {
                        this.routerMap[key] = {
                            action: rule,
                            context: context
                        }
                    }
                }, this);
            },
            /**
             * set default router
             * @param router
             */
            setDefaultRouter: function (router) {
                this._defaultRouter = router;
            },
            /**
             * start router
             */
            run: function () {
                this.active = true;
                this._parseURL();
            },
            /**
             * execute certain router handler
             * @param router
             * @param params
             */
            exec: function (router, params) {
                var rule, params;
                if (router) {
                    if (this.routerMap[router]) {
                        rule = this.routerMap[router];
                    } else {
                        rule = util.find(this.routerRegMap, function (rule) {
                            return !!router.match(rule.reg);
                        })
                    }
                }

                if (rule == null && this._defaultRouter) {
                    rule = this.routerMap[this._defaultRouter];
                }

                if (rule) {
                    rule.action.call(rule.context, params);
                }
            },
            _isRegExp: function (str) {
                return str.substr(0, 1) == "/";
            }
        }
    })

})(fruit, fruit.util, fruit.dom, fruit.ui.Element, fruit.global);